﻿using Godot;
using System;
using Dictionary = Godot.Collections.Dictionary;
public class BlockData
{
    public bool IsUpdate = false;
    //public bool IsTicked = false;
    public LargeChunk chunk;
    public Vector3I position;
    public Vector3I GlobalPosition;
    public BlockMaterial material;
    ItemMateria itemmaterial;
    public String Name;
    public int power;
    public int State;
    public int Rotate;
    public BlockEntity blockEntity;
    public Dictionary data = new Dictionary();
    public BlockData()
    {

    }
    public void SetState(int s)
    {
        State = s;
        chunk?.Updatelist.Add(position);
    }
    public void SetRotate(int s)
    {
        Rotate = s;
        chunk?.Updatelist.Add(position);
    }
    public BlockMaterial GetMaterial()
    {
        if (material == null || Name != material.Name)
            material = Materials.GetBlockMaterial(Name);
        return material;
    }
    public ItemMateria GetItemMaterial()
    {
        if (itemmaterial == null || Name != itemmaterial.Name)
            itemmaterial = Materials.GetItemMateria(Name);
        return itemmaterial;
    }
    public Dictionary GetDictionary()
    {
        Dictionary dict = new Dictionary
        {
            { "name", Name },
            { "State", State },
            { "rotate", Rotate }
        };
        if (data.Count > 0) dict.Add("data", data);
        if (blockEntity != null) dict.Add("BlockEntity", blockEntity.getDict());
        return dict;
    }
    public BlockData Parse(Dictionary dict)
    {
        this.Name = (string)dict["name"];
        this.State = dict["State"].ToInt();
        this.Rotate = dict["rotate"].ToInt();
        if (dict.Contains("data")) this.data = (Dictionary)dict["data"];
        if (dict.Contains("BlockEntity")) this.blockEntity = GetMaterial().CreateBlockEntity().JsonTo((Dictionary)dict["BlockEntity"]);
        return this;
    }
    public String ToJson()
    {
        return JSON.Print(GetDictionary());
    }



    //大量调用,谨慎更新
    public BlockData SetBlock(BlockMaterial bm, int state = 0)
    {
        IsUpdate = false;
        if (chunk == null)
        {
            GD.PrintErr(".SetBlock() chunk is null!");
        }
        this.Rotate = 0;
        this.State = state;
        this.Name = bm.Name;
        this.blockEntity = null;
        this.material = bm;
        if (bm.CreateBlockEntity != null) this.blockEntity = bm.CreateBlockEntity();
        chunk?.Updatelist.Add(position);
        return this;
    }


    public int GetTileId()
    {
        if (material != null)
            return material.GetTileId(this);
        else return Materials.GetBlockMaterial(Name).GetTileId(this);
    }
    //
    public FluidData GetFluid(string name)
    {
        if (blockEntity == null) return null;
        return blockEntity.GetFluid(name);
    }
}
